<!--
 * @Date: 2023-01-11 20:40:56
 * @LastEditTime: 2023-09-12 16:42:13
 * 介绍:列表组件
-->
<script lang="ts" setup name="List" generic="F extends Api">
import RpullRefresh from "@@/components/rework/RpullRefresh/RpullRefresh.vue";
import useRequestList, {
  GetRequestBefore,
  Api,
  GetParams,
} from "@@/hooks/useRequestList";

const props = withDefaults(
  defineProps<{
    minHeight?: string;
    /**api接口 */
    api: F;
    /**发起请求前 */
    reqBefore?: GetRequestBefore<F>;
    sticky?: boolean;
    /**是否非分页接口 */
    isOnePage?: boolean;
    /**是否使用下拉刷新 */
    pullRefresh?: boolean;
    transitionGroup?: string | false;
    offsetTop?: string;
    extraParams?: any[];
    params?: GetParams<F>;
  }>(),
  {
    minHeight: "50vh",
    pullRefresh: true,
    transitionGroup: "CrequestList",
    offsetTop: "110rem",
  }
);

const emit = defineEmits(["scroll", "load", "refresh"]);
function load() {
  emit("load");
  request();
}

/**下拉刷新 */
const PullRefreshRef = ref<InstanceType<typeof RpullRefresh>>();
/**监听下拉刷新 */
async function onRefresh() {
  emit("refresh");
  pullDownStart();
  const res = await rerequest();
  if (res.type === "error") return pullDownFail();
  pullDownSuccess();
}
/**下拉刷新成功 */
function pullDownSuccess() {
  PullRefreshRef.value?.success();
}
/**下拉刷新开始 */
function pullDownStart() {
  PullRefreshRef.value?.start();
}
/**下拉刷新失败 */
function pullDownFail() {
  PullRefreshRef.value?.fail();
}
const {
  data,
  state,
  res,
  request,
  rerequest,
  stateEnd,
  stateErr,
  stateLoading,
  stateNull,
  stateNext,
} = useRequestList(props.api, {
  isOnePage: props.isOnePage,
  requestBefore: props.reqBefore,
  returnExtraParams: () => props.extraParams || [],
  returnParams: () => props.params || {},
});
/**暴露分页hooks */
defineExpose({
  rerequest,
  state,
  data,
  res,
  stateEnd,
  stateErr,
  stateLoading,
  stateNull,
  stateNext,
});
</script>
<template>
  <div class="CrequestList">
    <van-sticky v-if="sticky" :offset-top="offsetTop" position="top">
      <slot name="header"></slot>
    </van-sticky>
    <slot v-else name="header"></slot>

    <RpullRefresh
      :disabled="!pullRefresh"
      ref="PullRefreshRef"
      @refresh="onRefresh"
    >
      <van-list
        :loading="state.type === 'loading'"
        :finished="state.type === 'end' || state.type === 'null'"
        :error="state.type === 'error'"
        @load="load"
        class="CrequestList_list"
        :style="{ minHeight }"
      >
        <slot :list="data">
          <!-- 循环渲染 -->
          <div class="auto-MT-sm CrequestList_default">
            <TransitionGroup v-if="transitionGroup" :name="transitionGroup">
              <slot
                v-for="(item, index) in data"
                name="item"
                :item="item"
                :index="index"
              >
              </slot>
            </TransitionGroup>
            <slot
              v-else
              v-for="(item, index) in data"
              name="item"
              :item="item"
              :index="index"
            >
            </slot>
          </div>
        </slot>
        <ClistState :type="state.type" :message="state.message" />
        <template #error> </template>
        <template #loading> </template>
        <template #finished> </template>
      </van-list>
    </RpullRefresh>
  </div>
</template>

<style lang="scss" scoped>
.CrequestList {
  .CrequestList_default {
    margin-bottom: var(--gap-md);
  }
}
</style>
